﻿#include "symnode.h"
#include "global.h"
#include <QDateTime>


//1000 函数 1001 作用域
SymNode::SymNode()
{
    type = UNUSE_SYM;
    value.vpoint = 0;
    funRetValue = 0;
}

//获取结构体变量的结构类型
 std::string SymNode::getStructType()
{
     if(this->type == EXPR_STRUCT && this->value.vpoint != nullptr)
     {
         STRUCT_VALUE_DATA* pValue = (STRUCT_VALUE_DATA*)this->value.vpoint;
         return pValue->structType;
     }
     return this->name;//避免返回空，导致都为空相等。
}



int SymNode::getStructTypeId()
{
    if(this->type == EXPR_STRUCT && this->value.vpoint != nullptr)
    {
        STRUCT_VALUE_DATA* pValue = (STRUCT_VALUE_DATA*)this->value.vpoint;
        return pValue->structTypeId;
    }
    return Struct_Unkonwn_ID;
}

QString SymNode::toString()
{

    switch(type)
    {
    case EXPR_INT:
        return QString("%1").arg(value.vint);
    case EXPR_INT64:
        return QString("%1").arg(value.vint64);
    case EXPR_FLOAT:
        return QString("%1").arg(value.vfloat);
    case EXPR_STRING:
    {
        if(value.vpoint != nullptr)
        {
            return QString(*(QByteArray*)value.vpoint);
        }

        return "";
    }
    case EXPR_BOOL:
        return QString("%1").arg(value.vbool ? "zhen":"jia");
    case EXPR_CHAR:
         return QString("'%1'").arg(value.vchar);
    default:
        return "";
    }
}

//不放入到析构函数，外面调用。之前发现macos析构函数可能多次进入
void SymNode::destory()
{
    switch(type)
    {
    case EXPR_STRING:
        if(value.vpoint != nullptr)
        {
            delete (QByteArray*)value.vpoint;
            value.vpoint = nullptr;
#ifdef PIN_MEM_REF
            freeTimes++;
#endif
        }
        break;

    case EXPR_U16STRING:
        if (value.vpoint != nullptr)
        {
            delete (QString*)value.vpoint;
            value.vpoint = nullptr;
#ifdef PIN_MEM_REF
            freeTimes++;
#endif
        }
        break;

    case EXPR_STRUCT_DEC:
        if(value.vpoint != nullptr)
        {
            delete (std::vector<std::string>*)value.vpoint;
            value.vpoint = nullptr;
#ifdef PIN_MEM_REF
            freeTimes++;
#endif
        }
        break;

    case EXPR_STRUCT:
        if(value.vpoint != nullptr)
        {
            STRUCT_VALUE_DATA_* pData =  (STRUCT_VALUE_DATA_*)value.vpoint;
            //通过把STRUCT_VALUE_DATA_ 数据放在结构图的第一个，变相解决该问题。
            std::vector<ExprValue*>* exprVec = (std::vector<ExprValue*>*)(pData->pValue);

            if(exprVec != nullptr)
            {
                for(int i=0,c = exprVec->size(); i < c; ++i)
                {
                    exprVec->operator [](i)->freeMem();
                    delete exprVec->operator [](i);
#ifdef PIN_MEM_REF
                    freeTimes++;
#endif
                }
                delete exprVec;
#ifdef PIN_MEM_REF
                freeTimes++;
#endif
            }
            delete pData;
#ifdef PIN_MEM_REF
            freeTimes++;
#endif
            value.vpoint = nullptr;

        }
        break;
    case EXPR_LIST:
        if(value.vpoint != nullptr)
        {
            //引用计数结果为0则删除，不是0，则不真正删除内存，其它地方还在使用
            //之前有，则看看引用计算后，能否删除
            if(0 == subListMapRefNum(this->value.vpoint))
            {
#ifdef PIN_DEBUG
                std::cout << u8"释放列表" << this->name << std::endl;
#endif
                std::vector<ExprValue_*>* pData = (std::vector<ExprValue_*>*)this->value.vpoint;


                for(int i=0, c= pData->size(); i <c; ++i)
                {

                    (*pData)[i]->freeMem();
                    delete (ExprValue_*)((*pData)[i]);
					#ifdef PIN_MEM_REF
        freeTimes++;
#endif
                }
                delete pData;
                value.vpoint = nullptr;
#ifdef PIN_MEM_REF
                freeTimes++;
#endif
            }
            else
            {
                value.vpoint = nullptr;
            }
        }
        break;

    case EXPR_MAP:
        if(value.vpoint != nullptr)
        {
            if(0 == subListMapRefNum(value.vpoint))
            {
                std::unordered_map<ExprValue_, ExprValue_*>* pData = (std::unordered_map<ExprValue_, ExprValue_*>*)value.vpoint;

                for (std::unordered_map<ExprValue_, ExprValue_*>::iterator it = pData->begin(); it != pData->end(); ++it)
                {
                    ExprValue_ key = it->first;
                    key.freeMem();

                    it->second->freeMem();
                    delete it->second;
					#ifdef PIN_MEM_REF
        freeTimes++;
#endif
                }

                delete pData;

                value.vpoint = nullptr;
#ifdef PIN_MEM_REF
                freeTimes++;
#endif
            }
            else
            {
                value.vpoint = nullptr;
            }

        }
        break;
    case EXPR_FILE:
        if(value.vpoint != nullptr)
        {
            //引用计数结果为0则删除，不是0，则不真正删除内存，其它地方还在使用
            //之前有，则看看引用计算后，能否删除
            if(0 == subListMapRefNum(this->value.vpoint))
            {

                FILE_VALUE_DATA* pData = (FILE_VALUE_DATA*)this->value.vpoint;
#ifdef PIN_DEBUG

               // std::cout << u8"--释放文件" << pData->pFileInfo->absoluteFilePath().toStdString() << std::endl;
#endif
                pData->destory();

                delete pData;
                value.vpoint = nullptr;
#ifdef PIN_MEM_REF
                freeTimes++;
#endif
            }
            else
            {
                value.vpoint = nullptr;
            }
        }
        break;
    case EXPR_EXCEL:
    {
        if (value.vpoint != nullptr)
        {
            //引用计数结果为0则删除，不是0，则不真正删除内存，其它地方还在使用
            //之前有，则看看引用计算后，能否删除
            if (0 == subListMapRefNum(this->value.vpoint))
            {

                EXCEL_VALUE_DATA* pData = (EXCEL_VALUE_DATA*)this->value.vpoint;
#ifdef PIN_DEBUG

                // std::cout << u8"--释放文件" << pData->pFileInfo->absoluteFilePath().toStdString() << std::endl;
#endif
                pData->destory();

                delete pData;
                value.vpoint = nullptr;
#ifdef PIN_MEM_REF
                freeTimes++;
#endif
            }
            else
            {
                value.vpoint = nullptr;
            }
        }
    }
        break;
    case EXPR_DATE:
        if (value.vpoint != nullptr)
        {
            QDateTime* pData = (QDateTime*)value.vpoint;
            delete pData;
#ifdef PIN_MEM_REF
            freeTimes ++;
#endif
            value.vpoint = nullptr;

        }
        break;
    case ERR_INFO:
    {
        if (value.vpoint != nullptr)
        {
            delete (ERR_DATA_INFO*)value.vpoint;
            value.vpoint = nullptr;
#ifdef PIN_MEM_REF
            freeTimes ++;
#endif
        }
    }
        break;
    case EXPR_FUN:
    case HD_TO_HS_INFO:
    case EXPR_CALL_BACK_FUN:
    {
        if (value.vpoint != nullptr)
        {
            delete (std::string*)value.vpoint;
            value.vpoint = nullptr;
#ifdef PIN_MEM_REF
            freeTimes ++;
#endif
        }
    }
        break;
    case TIPS_INFO:
    {
        if (value.vpoint != nullptr)
        {
            delete (QString*)(value.vpoint);
            value.vpoint = nullptr;
#ifdef PIN_MEM_REF
            freeTimes++;
#endif
        }
    }
    break;
    case EXPR_MULTI_FUN_CALL_CTX:
    {
        if (value.vpoint != nullptr)
        {
         value.vpoint = nullptr;
        }
    }
        break;

    /*case HD_TO_HS_INFO:
    {
        if (value.vpoint != nullptr)
        {
            delete (std::string*)value.vpoint;
            value.vpoint = nullptr;
#ifdef PIN_MEM_REF
            freeTimes++;
#endif
        }
    }
    break;*/
    default:
        this->value.vpoint = 0;
        break;

    }

}
